import { type Variants } from 'framer-motion';

/**
 * 动画增强系统
 *
 * 🎯 设计理念：
 * 1. 预设与自定义结合：提供常用预设，支持完全自定义
 * 2. 物理引擎集成：支持弹性动画 (spring) 和传统缓动函数
 * 3. 连锁动画：支持多元素错峰动画效果
 * 4. 性能优化：根据设备性能和用户偏好调整动画复杂度
 *
 * 🎬 动画预设系统：
 * - smoothSlide: 平滑滑动 (300ms, easeOut)
 * - springy: 弹性动画 (500ms, spring physics)
 * - snappy: 快速响应 (200ms, easeIn)
 * - dramatic: 戏剧效果 (600ms, backOut + spring)
 * - staggered: 错峰动画 (400ms + 50ms stagger)
 * - custom: 完全自定义配置
 *
 * 🌊 缓动函数库：
 * - 标准缓动：linear, easeIn, easeOut, easeInOut
 * - 圆形缓动：circIn, circOut, circInOut
 * - 回弹缓动：backIn, backOut, backInOut
 * - 弹跳缓动：bounceIn, bounceOut, bounceInOut
 * - 预期缓动：anticipate (先后退再前进)
 *
 * 🏗️ 架构设计：
 * - 工厂模式：AnimationVariantGenerator 根据配置生成变体
 * - 策略模式：不同动画类型使用不同策略
 * - 组合模式：支持多种动画效果组合
 *
 * ⚡ 性能考虑：
 * - GPU 加速：优先使用 transform 和 opacity
 * - 减少重排：避免修改 layout 属性
 * - 用户偏好：支持 prefers-reduced-motion
 */

/**
 * 缓动函数类型
 */
export type EasingFunction =
  | 'linear'
  | 'easeIn'
  | 'easeOut'
  | 'easeInOut'
  | 'circIn'
  | 'circOut'
  | 'circInOut'
  | 'backIn'
  | 'backOut'
  | 'backInOut'
  | 'anticipate'
  | 'bounceIn'
  | 'bounceOut'
  | 'bounceInOut'
  | number[]
  | ((t: number) => number);

/**
 * 动画配置接口
 */
export interface AnimationConfig {
  /** 动画持续时间 (ms) */
  duration?: number;
  /** 缓动函数 */
  easing?: EasingFunction;
  /** 延迟时间 (ms) */
  delay?: number;
  /** 是否启用弹性动画 */
  enableSpring?: boolean;
  /** 弹性动画配置 */
  spring?: {
    stiffness?: number;
    damping?: number;
    mass?: number;
  };
}

/**
 * 连锁动画配置
 */
export interface ChainAnimationConfig {
  /** 是否启用连锁动画 */
  enabled?: boolean;
  /** 连锁延迟时间 (ms) */
  stagger?: number;
  /** 连锁方向 */
  direction?: 'normal' | 'reverse';
}

/**
 * 预定义的缓动函数
 */
export const EASING_FUNCTIONS = {
  // 标准缓动
  linear: [0, 0, 1, 1],
  easeIn: [0.4, 0, 1, 1],
  easeOut: [0, 0, 0.2, 1],
  easeInOut: [0.4, 0, 0.2, 1],

  // 圆形缓动
  circIn: [0.6, 0.04, 0.98, 0.34],
  circOut: [0.08, 0.82, 0.17, 1],
  circInOut: [0.78, 0.14, 0.15, 0.86],

  // 回弹缓动
  backIn: [0.6, -0.28, 0.74, 0.05],
  backOut: [0.18, 0.89, 0.32, 1.28],
  backInOut: [0.68, -0.55, 0.265, 1.55],

  // 弹跳缓动
  bounceOut: [0.34, 1.56, 0.64, 1],
  bounceIn: [0.36, 0, 0.66, -0.56],
  bounceInOut: [0.68, -0.55, 0.265, 1.55],

  // 预期动画（先后退再前进）
  anticipate: [0.22, 1, 0.36, 1],
} as const;

/**
 * 动画变体生成器
 */
export class AnimationVariantGenerator {
  private config: AnimationConfig;
  private chainConfig: ChainAnimationConfig;

  constructor(
    config: AnimationConfig = {},
    chainConfig: ChainAnimationConfig = {}
  ) {
    this.config = {
      duration: 300,
      easing: 'easeOut',
      delay: 0,
      enableSpring: false,
      spring: {
        stiffness: 300,
        damping: 30,
        mass: 1,
      },
      ...config,
    };

    this.chainConfig = {
      enabled: false,
      stagger: 50,
      direction: 'normal',
      ...chainConfig,
    };
  }

  // 公共访问器
  get animationConfig() {
    return this.config;
  }

  get chainAnimationConfig() {
    return this.chainConfig;
  }

  /**
   * 获取缓动函数
   */
  private getEasing(): any {
    const { easing } = this.config;

    if (typeof easing === 'string' && easing in EASING_FUNCTIONS) {
      return EASING_FUNCTIONS[easing as keyof typeof EASING_FUNCTIONS];
    }

    return easing;
  }

  /**
   * 获取过渡配置
   */
  private getTransition(customDelay = 0): any {
    const { duration, delay, enableSpring, spring } = this.config;

    const baseTransition = {
      duration: (duration! + customDelay) / 1000,
      delay: delay! / 1000,
    };

    if (enableSpring) {
      return {
        type: 'spring',
        stiffness: spring!.stiffness,
        damping: spring!.damping,
        mass: spring!.mass,
        delay: (delay! + customDelay) / 1000,
      };
    }

    return {
      ...baseTransition,
      ease: this.getEasing(),
    };
  }

  /**
   * 生成滑入动画变体
   */
  generateSlideVariants(
    position: 'top' | 'bottom' | 'left' | 'right'
  ): Variants {
    const getInitialTransform = () => {
      switch (position) {
        case 'top':
          return { y: '-100%' };
        case 'bottom':
          return { y: '100%' };
        case 'left':
          return { x: '100%' };
        case 'right':
          return { x: '-100%' };
        default:
          return { y: '100%' };
      }
    };

    return {
      hidden: {
        ...getInitialTransform(),
        opacity: 0,
        scale: 0.95,
      },
      visible: {
        x: 0,
        y: 0,
        opacity: 1,
        scale: 1,
        transition: this.getTransition(),
      },
      exit: {
        ...getInitialTransform(),
        opacity: 0,
        scale: 0.95,
        transition: this.getTransition(),
      },
    };
  }

  /**
   * 生成缩放动画变体
   */
  generateScaleVariants(): Variants {
    return {
      hidden: {
        scale: 0,
        opacity: 0,
        rotate: -10,
      },
      visible: {
        scale: 1,
        opacity: 1,
        rotate: 0,
        transition: this.getTransition(),
      },
      exit: {
        scale: 0,
        opacity: 0,
        rotate: 10,
        transition: this.getTransition(),
      },
    };
  }

  /**
   * 生成淡入动画变体
   */
  generateFadeVariants(): Variants {
    return {
      hidden: {
        opacity: 0,
        y: 20,
      },
      visible: {
        opacity: 1,
        y: 0,
        transition: this.getTransition(),
      },
      exit: {
        opacity: 0,
        y: -20,
        transition: this.getTransition(),
      },
    };
  }

  /**
   * 生成弹性动画变体
   */
  generateBounceVariants(): Variants {
    return {
      hidden: {
        scale: 0,
        opacity: 0,
      },
      visible: {
        scale: 1,
        opacity: 1,
        transition: {
          type: 'spring',
          stiffness: 400,
          damping: 10,
          delay: this.config.delay! / 1000,
        },
      },
      exit: {
        scale: 0,
        opacity: 0,
        transition: this.getTransition(),
      },
    };
  }

  /**
   * 生成连锁动画变体
   */
  generateChainVariants(itemCount: number): Variants[] {
    if (!this.chainConfig.enabled) {
      return [];
    }

    const variants: Variants[] = [];
    const { stagger, direction } = this.chainConfig;

    for (let i = 0; i < itemCount; i++) {
      const delay =
        direction === 'reverse' ? (itemCount - 1 - i) * stagger! : i * stagger!;

      variants.push({
        hidden: {
          opacity: 0,
          y: 20,
        },
        visible: {
          opacity: 1,
          y: 0,
          transition: this.getTransition(delay),
        },
        exit: {
          opacity: 0,
          y: -20,
          transition: this.getTransition(delay),
        },
      });
    }

    return variants;
  }

  /**
   * 生成自定义动画变体
   */
  generateCustomVariants(
    hidden: Record<string, any>,
    visible: Record<string, any>,
    exit?: Record<string, any>
  ): Variants {
    return {
      hidden,
      visible: {
        ...visible,
        transition: this.getTransition(),
      },
      exit: {
        ...(exit || hidden),
        transition: this.getTransition(),
      },
    };
  }
}

/**
 * 动画预设
 */
export const ANIMATION_PRESETS = {
  // 流畅滑入
  smoothSlide: new AnimationVariantGenerator({
    duration: 400,
    easing: 'easeOut',
    enableSpring: false,
  }),

  // 弹性动画
  springy: new AnimationVariantGenerator({
    duration: 500,
    enableSpring: true,
    spring: {
      stiffness: 300,
      damping: 25,
      mass: 1,
    },
  }),

  // 快速响应
  snappy: new AnimationVariantGenerator({
    duration: 200,
    easing: 'easeInOut',
  }),

  // 戏剧性效果
  dramatic: new AnimationVariantGenerator({
    duration: 600,
    easing: 'backOut',
  }),

  // 连锁动画
  staggered: new AnimationVariantGenerator(
    {
      duration: 300,
      easing: 'easeOut',
    },
    {
      enabled: true,
      stagger: 100,
      direction: 'normal',
    }
  ),
} as const;
